<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #d1 {
      height: 4000px;
      width: 400px;
      border: 1px solid red;
    }

    #d2 {
      height: 300px;
      width: 300px;
      border: 1px solid blue;
    }

    #d3 {
      height: 200px;
      width: 200px;
      border: 1px solid green;
    }

    .d3 {
      height: 600px;
      width: 200px;
      border: 1px solid green;
    }

    .d {
      width: 100%;
      border-color: brown;
    }
  </style>
</head>

<body>
  <button onclick="handleScroll()">滚动到d的位置</button>
  <div id="d1">
    <div id="d2">
      <div id="d3"></div>
    </div>
    <div class="d3"></div>
    <div class="d3"></div>
    <div class="d3 d">我是d</div>
  </div>
  <script>
    /* 点击事件 */
    // addEventListener(type, listener);
    // addEventListener(type, listener, options);
    // options中
    // 可以设置 capture 属性，值为布尔值，表示事件是否在捕获阶段执行
    // 可以设置 once 属性，值为布尔值，表示是否只触发一次
    // 可以设置 passive 属性，值为布尔值，表示是否阻止事件的默认行为
    // 可以设置 signal 属性，值为布尔值 该  AbortSignal 的 abort() 方法被调用时，监听器会被移除
    // addEventListener(type, listener, useCapture);
    // useCapture 表示事件是否在捕获阶段执行 boolean 默认为 false
    document.getElementById('d1').addEventListener('click', function () {
      console.log('我是d1')
    });
    document.getElementById('d2').addEventListener('click', function () {
      console.log('我是d2')
    }, true);
    document.getElementById('d3').addEventListener('click', function () {
      // 阻止事件冒泡
      // e.stopPropagation();
      // 打印出"我是d3"
      console.log('我是d3')
    })

    /* 滚动测试 */
    window.addEventListener('scroll', scrollMethod)

    function scrollMethod() {
      // 页面高度
      let documentHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
      // 窗口高度 - 可视高度
      let windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
      // 滚动条位置
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

      // 目标元素距离页面顶部距离
      let targetEleTop = document.querySelector('.d').offsetTop;
      if ((windowHeight + scrollTop) >= targetEleTop) {
        // console.log("window.addEventListener('scroll' 页面滚动到达指定元素了");
      }
      if ((windowHeight + scrollTop) == documentHeight) {
        // console.log("window.addEventListener('scroll' 页面滚动到达底部");
      }
    };

    /* 让页面滚动到某个位置 */
    function handleScroll() {
      let t = document.querySelector('.d').offsetTop
      /* 使界面滚动到给定元素的指定坐标位置 */
      /* 一 使用 window.scrollTo */
      // scrollTo(x-coord, y-coord)
      //     x-coord 水平位置
      //     y-coord 垂直位置
      //   scrollTo(options)
      //     options 中包括三个属性
      //       top 指定沿 Y 轴滚动窗口或元素的像素数
      //       left 指定沿 X 轴滚动窗口或元素的像素数
      //       behavior 指定动画效果，可选 instant | smooth | auto 
      //         默认 auto 自动选择滚动效果
      //         instant 没有动画 直接滚动
      //         smooth 平滑滚动有过渡效果
      // window.scrollTo(0, t)
      // window.scrollTo({ top: t, behavior: 'smooth' })
      // window.scrollTo({ top: t, behavior: 'instant' })

      /* 二 使用 scrollTop （ 该方法无法使用过渡效果 ） */
      // document.documentElement.scrollTop = t;
      // document.body.scrollTop = t;

      /* 三 使用 scrollIntoView */
      // document.querySelector('.d').scrollIntoView()// 默认值为true
      // document.querySelector('.d').scrollIntoView(true)// 元素顶端与视口齐平
      // document.querySelector('.d').scrollIntoView(false)// 元素底端与视口齐平
    }

    /* 使用 IntersectionObserver API 实现滚动加载 */
    const d = document.querySelector('.d');
    const intersectionObserver = new IntersectionObserver((entries) => {
      entries.forEach((item) => {
        if (item.isIntersecting) { console.log('进入可视区域'); }
      })
    });
    intersectionObserver.observe(d);

    const io = new IntersectionObserver(
      (entries) => { console.log(entries); },
      {
        threshold: [0, 0.5], root: document.querySelector('body'), rootMargin: "10px 10px 30px 20px",
      }
    );
  </script>
</body>

</html>